/*!
\copyright  Copyright (c) 2022 Qualcomm Technologies International, Ltd.
            All Rights Reserved.
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\file
\brief
*/

#if defined(INCLUDE_LE_AUDIO_UNICAST) && defined(ENABLE_MULTIPOINT) && defined(ENABLE_LE_AUDIO_RESTRICTED_MULTIPOINT)

#include "le_unicast_manager_feature.h"
#include "le_unicast_manager_private.h"
#include "telephony_messages.h"
#include "av.h"
#include <panic.h>

static feature_state_t leUnicastManager_GetFeatureState(void);
static void leUnicastManager_FeatureSuspend(void);
static void leUnicastManager_FeatureResume(void);

static const feature_interface_t le_unicast_feature_if =
{
    .GetState = leUnicastManager_GetFeatureState,
    .Suspend = leUnicastManager_FeatureSuspend,
    .Resume = leUnicastManager_FeatureResume,
};


static feature_state_t leUnicastManager_GetFeatureState(void)
{
    return LeUnicastManager_GetContext()->feature_context.state;
}

static void leUnicastManager_FeatureSuspend(void)
{
    /* Resume function is expected for lower priority feature,
       but in unciast case need not do any actions as both broadcast and unicast
       disconnects other link and we won't end up in this situation.
    */
}

static void leUnicastManager_FeatureResume(void)
{
    /* Suspend function is expected for lower priority feature,
       but in unicast case need not do any actions as both broadcast and unicast
       disconnects other link and we won't end up in this situation.
    */
}

void LeUnicastManager_UpdateFeatureAllowedStatus(bool is_allowed)
{
    le_um_feature_context_t *feature_context = &LeUnicastManager_GetContext()->feature_context;

    DEBUG_LOG_INFO("LeUnicastManager_UpdateFeatureAllowedStatus is_allowed: %d, available_context (src: 0x%x, snk: 0x%x)",
                   is_allowed, feature_context->saved_sink_available_context, feature_context->saved_source_available_context);

    if (is_allowed && (feature_context->saved_sink_available_context != 0 || feature_context->saved_source_available_context != 0))
    {
        LeUnicastManager_RestoreSinkAudioContext(feature_context->saved_sink_available_context);
        LeUnicastManager_RestoreSourceAudioContext(feature_context->saved_source_available_context);
        feature_context->saved_sink_available_context = feature_context->saved_source_available_context = 0;
    }
    else if (!is_allowed && (feature_context->saved_sink_available_context == 0 || feature_context->saved_source_available_context == 0))
    {
        feature_context->saved_sink_available_context = LeBapPacsUtilities_GetSinkAudioContextAvailability();
        feature_context->saved_source_available_context = LeBapPacsUtilities_GetSourceAudioContextAvailability();

        LeUnicastManager_ClaimSinkAudioContext(feature_context->saved_sink_available_context);
        LeUnicastManager_ClaimSourceAudioContext(feature_context->saved_source_available_context);
    }
}

void LeUnicastManager_FeatureInit(void)
{
    le_um_feature_context_t *feature_context = &LeUnicastManager_GetContext()->feature_context;

    LeUnicastManager_SetFeatureHandle(FeatureManager_Register(feature_id_le_unicast, &le_unicast_feature_if));
    LeUnicastManager_SetFeatureState(feature_state_idle);

    feature_context->saved_sink_available_context = feature_context->saved_source_available_context = 0;

    /* Temporarily use the hfp_profile notifications to know when a call
       starts and ends. Use av status notifications for when A2DP media
       streaming starts and end.

       Eventually this behaviour will be driven by the audio router pausing
       and resuming broadcast when a call is active.*/
    appAvStatusClientRegister(LeUnicastManager_GetTask());
    Telephony_RegisterForMessages(LeUnicastManager_GetTask());
}

void LeUnicastManager_FeatureStart(void)
{
    if (feature_state_idle == leUnicastManager_GetFeatureState())
    {
        if (FeatureManager_StartFeatureRequest(LeUnicastManager_GetFeatureHandle()))
        {
            LeUnicastManager_SetFeatureState(feature_state_running);
        }
    }
}

void LeUnicastManager_FeatureStop(void)
{
    if (feature_state_running == leUnicastManager_GetFeatureState())
    {
        LeUnicastManager_SetFeatureState(feature_state_idle);
        FeatureManager_StopFeatureIndication(LeUnicastManager_GetFeatureHandle());
    }
}

#endif /* defined(INCLUDE_LE_AUDIO_UNICAST) && defined(ENABLE_MULTIPOINT) && defined(ENABLE_LE_AUDIO_RESTRICTED_MULTIPOINT) */
